﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

namespace Gluten.Models
{
    public class DBManager
    {
        private readonly DataBaseContext _db = new DataBaseContext();

        // methods for Menu

        public void AddMenu(Menu menu)
        {
            _db.Menus.Add(menu);
            _db.SaveChanges();
        }

        public void UpdateMenu(Menu menu)
        {
            _db.Menus.Remove(_db.Menus.Single(x => x.Id == menu.Id));
            _db.Menus.Add(menu);
            _db.SaveChanges();
        }

        public IQueryable<Menu> GetAllMenu()
        {
            return _db.Menus;
        }

        public IQueryable<Menu> GetAllMainMenu()
        {
            return _db.Menus.Where(menu => menu.Parent == Guid.Empty).Where(menu => menu.Id != Guid.Empty);
        }

        public Menu GetMenu(Guid id)
        {
            return _db.Menus.SingleOrDefault(menu => menu.Id == id);
        }

        public IQueryable<Menu> GetAllSubmenu(Guid id)
        {
            return _db.Menus.Where(x => x.Parent == id);
        }

        public void DeleteMenu(Guid id)
        {
            foreach (var menu in _db.Menus.Where(x => x.Parent == id))
            {
                DeleteMenu(menu.Id);
            }
            foreach (var page in _db.Pages.Where(x => x.MenuParent == id))
            {
                _db.Pages.Remove(page);
            }
            _db.Menus.Remove(_db.Menus.Single(x => x.Id == id));
            _db.SaveChanges();
        }

        //method for Page

        public void AddPage(Page page)
        {
            page.AddTime = DateTime.Now;
            _db.Pages.Add(page);
            _db.SaveChanges();
        }

        public void UpdatePage(Page page)
        {
            _db.Pages.Remove(_db.Pages.Single(x => x.Id == page.Id));
            _db.Pages.Add(page);
            _db.SaveChanges();
        }

        public void MovePagesToMenu(Guid destination, List<Guid> pages)
        {
            foreach (var page in pages)
            {
                GetPage(page).MenuParent = destination;
                _db.SaveChanges();
            }
        }
        public IEnumerable<Page> GetAllPages(Boolean withHidden)
        {
            return _db.Pages.Where(page => page.Publication | withHidden).
                OrderByDescending(page => page.AddTime);
        }

        public IEnumerable<Page> GetAllPagesByMenu(Guid menuId, Boolean withHidden)
        {
            return _db.Pages.Where(page => page.MenuParent == menuId).
                Where(page => page.Publication | withHidden);
        }

        public Page GetPage(Guid id)
        {
            return _db.Pages.Single(menu => menu.Id == id);
        }

        public void DeletePages(List<Guid> pages)
        {
            foreach (var page in pages)
            {
                DeletePage(page);
            }
        }

        public void DeletePage(Guid id)
        {
            _db.Pages.Remove(_db.Pages.Single(x => x.Id == id));
            _db.SaveChanges();
        }

        // methods for Label

        public void AddLabel(Label label)
        {
            _db.Labels.Add(label);
            _db.SaveChanges();
        }

        public void UpdateLabel(Label label)
        {
            var labelFromDB = _db.Labels.SingleOrDefault(x => x.Id == label.Id);
            _db.Labels.Remove(labelFromDB);
            _db.Labels.Add(label);
            _db.SaveChanges();
        }

        public void LabelImageChange(Guid id, string imagePath)
        {
            _db.Labels.Single(label => label.Id == id).Image = imagePath;
            _db.SaveChanges();
        }

        public Label GetLabel(Guid labelId)
        {
            return _db.Labels.SingleOrDefault(x => x.Id == labelId);
        }

        public Label GetNearLabel(Guid labelId)
        {
            var labels = _db.Labels.Where(x => x.Id == labelId);
            if (labels.Any())
            {
                return labels.First();
            }
            return _db.Labels.SingleOrDefault(x => x.Id == Guid.Empty) ?? new Label {Id = Guid.Empty};
        }
    }
}